﻿using System;
using System.IO;
using CoreTypes;
using System.Custom.Window;
using System.Drawing;
using System.Reflection;
using System.Globalization;
using System.Windows.Forms;
using System.ComponentModel;
using MainModule.Properties;

namespace MainModule
{
   public partial class ErrorViewer : Window
   {
      Size FMaximumSize;
      InternetCommunicator FCommunicator = InternetCommunicator.Self;

      public ErrorViewer()
      {
         InitializeComponent();

         FMaximumSize = Size;

         pictureBoxIcon.Visible = labelMessage.Visible = false;

         FCommunicator.PropertyChanged += communicator_PropertyChanged;
         FCommunicator.InstallationCheck += communicator_CheckingUpdates;

         //Icon = Icon.FromHandle(GlobalResources.GetImage("TestCitronIcon11").GetHicon());
      }

      public void ShowMessage(string message)
      {
         Text = Resources.S_Info;
         Icon = SystemIcons.Information;
         pictureBoxIcon.Image = Resources.InfoVista;

         labelMessage.Text = message;
         labelInfo.Visible = buttonActions.Visible = buttonDetails.Visible = false;

         buttonDetails_Click(this, null);

         CenterToScreen();

         Visualize();
      }
      public static void ShowFatal(string message, Exception error)
      {
         if (error == null) return;

         try
         {
            string msg = message + "\r\n" + error.Message;

            if (error != null)
            {
               msg += "\r\n\r\n\"" + error.Message + "\"";

               if (error.InnerException != null && error.InnerException.Message != error.Message)
               {
                  msg += "\r\n\r\n\"" + error.InnerException.Message + "\"";
               }
               if (!string.IsNullOrEmpty(error.StackTrace))
               {
                  msg += "\r\n\r\nStack:\r\n" + error.StackTrace;
               }
            }
            MessageBox.Show(msg, Resources.S_Error, MessageBoxButtons.OK, MessageBoxIcon.Stop);
         }
         catch
         {
            MessageBox.Show(error.ToString(), Resources.S_Error, MessageBoxButtons.OK, MessageBoxIcon.Stop);
         }
      }
      public void Show(string message, Exception error, MessageBoxIcon icon)
      {
         try
         {
            if (icon == MessageBoxIcon.Stop || icon == MessageBoxIcon.Error)
            {
               Icon = SystemIcons.Error;
               pictureBoxIcon.Image = Resources.ErrorVista;
            }
            else
            {
               Icon = SystemIcons.Warning;
               pictureBoxIcon.Image = Resources.WarningVista;
            }

            pictureBoxIcon.Image = icon == MessageBoxIcon.Stop || icon == MessageBoxIcon.Error ?
                                   Resources.ErrorVista : Resources.WarningVista;

            labelMessage.Text = message;
            textBoxDetails.Text = "";

            bool viewDetails = false;

            if (error is ServiceOperationException)
            {
               ServiceOperationException soex = error as ServiceOperationException;

               if (labelMessage.Text != "") labelMessage.Text += "\r\n\r\n";

               labelMessage.Text += soex.Reason;

               if (labelMessage.Text == "") labelMessage.Text += soex.Message;

               textBoxDetails.Text = soex.Message;

               viewDetails = textBoxDetails.Text != labelMessage.Text;
            }
            else if (error != null)
            {
               if (labelMessage.Text != "") labelMessage.Text += "\r\n\r\n";

               labelMessage.Text += error.Message;

               if (!string.IsNullOrEmpty(error.StackTrace))
               {
                  viewDetails = true;
                  textBoxDetails.Text += "\r\n\r\n--------------------------------------------------------------------------------------------------------------------------------------------------\r\n\r\n";
                  textBoxDetails.Text += "Call stack:\r\n\r\n" + error.StackTrace;
               }
               if (error.Data != null && error.Data.Count > 0)
               {
                  viewDetails = true;
                  textBoxDetails.Text += "\r\n\r\n--------------------------------------------------------------------------------------------------------------------------------------------------\r\n\r\n";
                  textBoxDetails.Text += "Exception data:\r\n\r\n";
                  foreach (var item in error.Data) textBoxDetails.Text += item.ToString() + "; ";
               }
               if (error.InnerException != null)
               {
                  viewDetails = true;
                  textBoxDetails.Text += "\r\n\r\n--------------------------------------------------------------------------------------------------------------------------------------------------\r\n\r\n";
                  textBoxDetails.Text += "Internal exception:\r\n\r\n";
                  textBoxDetails.Text += error.InnerException.ToString();
               }
               if (viewDetails) textBoxDetails.Text = textBoxDetails.Text.Insert(0, error.Message);
            }
            if (viewDetails)
            {
               textBoxDetails.Text += "\r\n\r\n--------------------------------------------------------------------------------------------------------------------------------------------------\r\n\r\n";
               textBoxDetails.Text += "Application version: " + Application.ProductVersion + "\r\n";
               string exePath = Assembly.GetExecutingAssembly().Location;
               textBoxDetails.Text += "Executable path: " + exePath + "\r\n";
               textBoxDetails.Text += "Build date: " + File.GetLastWriteTime(exePath).ToString() + "\r\n";
               textBoxDetails.Text += "Framework version: " + Environment.Version + "\r\n";
               textBoxDetails.Text += "System version: " + Environment.OSVersion + "\r\n";
               textBoxDetails.Text += "Machine name: " + Environment.MachineName + "\r\n";
               textBoxDetails.Text += "Event timestamp: " + DateTime.Now.ToString() + " (UTC " + DateTime.UtcNow.ToString() + ")\r\n\r\n";
               textBoxDetails.Text += "--------------------------------------------------------------------------------------------------------------------------------------------------\r\n";
            }
            buttonActions.Visible = true;
            menuItem1.Visible = viewDetails;
            menuItemSave.Visible = viewDetails;
            menuItemSend.Visible = viewDetails;
            menuItemExit.Visible = viewDetails;
            buttonDetails.Visible = viewDetails;
            labelInfo.Visible = viewDetails && string.IsNullOrEmpty(error.StackTrace) == false;
            labelInfo.Text = Resources.S_Click_Actions_to_check_updates;

            buttonDetails_Click(this, null);

            CenterToScreen();

            Visualize();
         }
         catch
         {
            ShowFatal(message, error);
         }
      }

      protected override void UpdatewWindowView()
      {
         labelInfo.Text = Resources.S_Click_Actions_to_check_updates;
         buttonDetails.Text = Resources.S_Details + (Size == FMaximumSize ? " <<" : " >>");
      }

      private void buttonClose_Click(object sender, EventArgs e)
      {
         Close();
      }
      private void window_SizeChanged(object sender, EventArgs e)
      {
         Refresh();
      }
      private void menuItemCopy_Click(object sender, EventArgs e)
      {
         Clipboard.SetText(textBoxDetails.Text);
      }
      private void menuItemSave_Click(object sender, EventArgs e)
      {
         string fileName = ("\\Error " + DateTime.Now.ToString() + ".txt").Replace(':', ' ');
         FileInfo fi = new FileInfo(Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory) + fileName);
         StreamWriter wr = fi.AppendText();
         wr.Write(textBoxDetails.Text);
         wr.Close();
         Close();
      }
      private void menuItemExit_Click(object sender, EventArgs e)
      {
         Application.Exit();
      }
      private void buttonActions_Click(object sender, EventArgs e)
      {
         contextMenuActions.Show(buttonActions, new Point(1, buttonActions.Height));
      }
      private void buttonDetails_Click(object sender, EventArgs e)
      {
         if (Size == FMaximumSize || e == null)
         {
            //FormBorderStyle = FormBorderStyle.FixedDialog;
            buttonDetails.Text = Resources.S_Details + " >>";
            Size = MinimumSize;
         }
         else
         {
            //FormBorderStyle = FormBorderStyle.Sizable;
            buttonDetails.Text = Resources.S_Details + " <<";
            Size = FMaximumSize;
         }
      }
      private void panelBase_Paint(object sender, PaintEventArgs e)
      {
         FCommunicator.DrawTheme(FCommunicator.ColorTheme, e.Graphics,
            (sender as Control).ClientRectangle, ColorThemeObject.Pattern);

         e.Graphics.DrawImageUnscaled(pictureBoxIcon.Image, pictureBoxIcon.Location);
         e.Graphics.DrawString(labelMessage.Text, labelMessage.Font, Brushes.DimGray, labelMessage.Bounds);
      }
      private void panelBottom_Paint(object sender, PaintEventArgs e)
      {
         FCommunicator.DrawTheme(FCommunicator.ColorTheme, e.Graphics,
            (sender as Control).ClientRectangle, ColorThemeObject.Area);
      }
      private void menuItemCheckUpdates_Click(object sender, EventArgs e)
      {
         FCommunicator.CheckInstallation(CheckInstallationArg.Update, "");
      }
      private void communicator_CheckingUpdates(object sender, InstallationCheckEventArgs e)
      {
         menuItemCheckUpdates.Enabled = true;

         switch (e.State)
         {
            case InstallationState.CheckInProgress:
            {
               labelInfo.Text = Resources.S_Checking_updates;
               menuItemCheckUpdates.Enabled = false;
               break;
            }
            case InstallationState.NoUpdates:
            {
               labelInfo.Text = Resources.S_You_are_using_the_latest_version;
               break;
            }
            case InstallationState.InstallReady:
            {
               labelInfo.Text = Resources.S_Updates_will_be_installed_automatically;
               break;
            }
            case InstallationState.ForcedInstall:
            {
               FCommunicator.Shutdown(true);
               Application.Restart();
               break;
            }
            default:
            {
               labelInfo.Text = Resources.S_Updates_are_unavailable;
               break;
            }
         }
         labelInfo.Visible = true;
      }
      private void communicator_PropertyChanged(object sender, PropertyChangedEventArgs e)
      {
         if (e.PropertyName == "ColorTheme") ColorTheme = FCommunicator.ColorTheme;
         else if (e.PropertyName == "Culture") Translate(FCommunicator.Culture);
      }
   }
}
